/// \brief
///   AECompiledTechnique represents a shader technique, typically consisting of one or multiple AECompiledShaderPass instances.
/// 
/// AECompiledTechnique and its AECompiledShaderPass instances can be passed to many rendering functions. Techniques are primarily
/// containers for shader passes and can contain multiple shader passes for multi-pass rendering. AECompiledTechnique instances
/// are generated from VShaderEffectTechnique objects and are specific for one parameter setup (in other words, there is a separate
/// AECompiledTechnique for each combination of shader parameters and VShaderEffectTechnique).
/// 
/// The AECompiledEffect class contains multiple AECompiledTechnique objects. The shader technique to be used for rendering is chosen
/// through a set of inclusion and exclusion tags.
class AECompiledTechnique : public AEReferencedObject
{
public:

  ///
  /// @name Constructor / Destructor
  /// @{
  ///


  /// \brief
  ///   Constructor. For internal use.
  inline AECompiledTechnique( AECompiledEffect *lpOwnerFX, const char *lpInclusionTags, const char *lpExclusionTags ) 
    : m_pOwnerFX(pOwnerFX)
    , m_Shaders()
    , m_Config(szInclusionTags,szExclusionTags)
    , m_ePassType(VPT_Undefined)
  {
  }

  /// \brief
  ///   Constructor. For internal use.
  inline AECompiledTechnique( AECompiledEffect *lpOwnerFX, AETechniqueConfig *lpConfig, 
    AEINT32 iPassCount=0, AECompiledShaderPass **lplpPasses = AENULL )
  {
    m_pOwnerFX = pOwnerFX;
    if (pConfig)
      m_Config = *pConfig; ///< use assignment operator

    m_Shaders.EnsureCapacity(iPassCount);
    for (AEINT32 i=0;i<iPassCount;i++)
    {
      pPasses[i]->m_bMayDeleteUnique = true;
      m_Shaders.Add(pPasses[i]);
    }
    EvaluatePassTypeFromPasses();
  }

  /// \brief
  ///   Destructor
  AE_DLLIMPEXP virtual ~AECompiledTechnique( void );

  /// \brief
  ///   Non-virtual override of the release function. In case refcounter reaches 1 and the force unique flag is set, the technique is deleted from the cache
  AE_DLLIMPEXP void Release( void );

  ///
  /// @}
  ///

  ///
  /// @name Accessing Shader Passes
  /// @{
  ///


  /// \brief
  ///   Returns the number of shader passes in this technique
  /// 
  /// This number can be used to iterate over the shader passes using GetShader(i)
  inline AEUINT32 GetShaderCount( void ) const {return m_Shaders.Count();}

  /// \brief
  ///   Returns a pointer to a list of pointers to all shader pass objects in this technique.
  inline AECompiledShaderPass **GetShaderList( void ) {return m_Shaders.GetPtrs();}

  /// \brief
  ///   Returns the n-th shader pass instance in this technique
  /// 
  /// The index is 0-based and must be in valid range [0..GetShaderCount()-1]
  /// 
  /// \param iIndex
  ///   0-based index
  /// 
  /// \return
  ///   AECompiledShaderPass *pPass : Instance that represents the shader pass with index iIndex
  inline AECompiledShaderPass *GetShader(AEINT32 iIndex) const {return m_Shaders.GetAt(iIndex);}

  /// \brief
  ///   Sets the state group mask for all passes.
  ///
  /// The state group mask of a shader defines which state groups (e.g. rasterizer state, blend state) should be set when
  /// enabling the shader pass. By excluding certains state groups, it becomes possible to override them using the functions in
  /// the VisRenderStates_cl class.
  ///
  /// \param iStateGroupMask
  ///   The state group mask to set.
  AE_DLLIMPEXP void SetStateGroupMaskForAllPasses(AEINT32 iStateGroupMask);

  ///
  /// @}
  ///

  ///
  /// @name Accessing Effect and Library
  /// @{
  ///

  /// \brief
  ///   Access the effect resource that has been used to create this compiled technique
  AE_DLLIMPEXP VShaderEffectResource *GetSourceEffect() const;

  /// \brief
  ///   Access the effect library resource that has been used to create this compiled technique
  AE_DLLIMPEXP VShaderEffectLib *GetOwnerEffectLib() const;

  /// \brief
  ///   Returns the parameter string that has been used to create this technique. Same as the parameter string of the source effect. 
  AE_DLLIMPEXP const char *GetParameterString() const;

  ///
  /// @}
  ///

  ///
  /// @name Internal Functions
  /// @{
  ///

  /// \brief
  ///   Loops through all shaders and evaluates the common pass type bitmask.
  AE_DLLIMPEXP void EvaluatePassTypeFromPasses();

  /// \brief
  ///   Returns all resources this compiled technique depends on.
  AE_DLLIMPEXP void GetDependencies(VResourceSnapshot &snapshot, VManagedResource *pOwner);

  ///
  /// @}
  ///

public:
  AECompiledEffect *m_pOwnerFX;
  VRefCountedCollection<AECompiledShaderPass> m_Shaders;
  AETechniqueConfig m_Config;
  VPassType_e m_ePassType;
};